﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Util
{
    public class WinApi
    {
        [DllImport( "../../Lib/KeyHook.dll" )]
        public static extern void HookStart ();

        [DllImport( "../../Lib/KeyHook.dll" )]
        public static extern void HookStop ();

        [DllImport( "user32.dll" )]
        public static extern IntPtr SetFocus ( IntPtr hWnd );

        [DllImport( "user32.dll" )]
        public static extern bool ShowWindow ( IntPtr hWnd, int nCmdShow );

        [DllImport( "user32.dll" )]
        public static extern BoundsSpecified BringWindowToTop ( IntPtr hWnd );

        [DllImport( "user32.dll", CharSet = CharSet.Auto, ExactSpelling = true )]
        public static extern IntPtr GetActiveWindow ();

        [DllImport( "user32", EntryPoint = "SetActiveWindow", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true )]
        public static extern long SetActiveWindow ( long hwnd );

        [DllImport( "user32.dll" )]
        public static extern IntPtr GetForegroundWindow ();

        [DllImport( "user32.dll" )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool SetForegroundWindow ( IntPtr hWnd );

        [DllImport( "user32.dll" )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool GetWindowRect ( IntPtr hWnd, out RECT lpRect );

        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Auto )]
        public static extern int GetWindowTextLength ( IntPtr hWnd );

        [DllImport( "user32.dll", SetLastError = true )]
        public static extern int GetWindowThreadProcessId ( IntPtr hWnd, out int lpdwProcessId );

        [DllImport( "user32.dll", SetLastError = true )]
        public static extern IntPtr FindWindow ( string lpClassName, string lpWindowName );

        // 현재 키의 눌려진 상태를 얻는다.
        [DllImport( "User32.dll", CharSet = CharSet.Auto )]
        public static extern short GetKeyState ( VirtualKeys Key_now );

        /// <summary>
        /// 키보드 이벤트
        /// </summary>
        /// <param name="bVk"></param>
        /// <param name="bScan"></param>
        /// <param name="dwFlags"></param>
        /// <param name="dwExtraInfo"></param>
        /// <returns></returns>
        [DllImport( "user32.dll" )]
        public static extern uint keybd_event ( byte bVk, byte bScan, int dwFlags, int dwExtraInfo );

        [DllImport( "imm32.dll" )]
        public static extern IntPtr ImmGetDefaultIMEWnd ( IntPtr hWnd );

        [DllImport( "imm32.dll" )]
        public static extern IntPtr ImmReleaseContext ( IntPtr hWnd, IntPtr hIMC );

        [DllImport( "imm32.dll" )]
        public static extern IntPtr ImmGetContext ( IntPtr hwnd );

        [DllImport( "imm32.dll" )]
        public static extern bool ImmGetOpenStatus ( IntPtr himc );

        [DllImport( "imm32.dll" )]
        public static extern bool ImmSetOpenStatus ( IntPtr himc, bool b );

        [DllImport( "imm32.dll" )]
        public static extern bool ImmGetConversionStatus ( IntPtr himc, ref int lpdw, ref int lpdw2 );

        [DllImport( "user32.dll", CharSet = CharSet.Auto )]
        public static extern IntPtr SendMessage ( IntPtr hWnd, uint Msg, uint wParam, uint Iparam );

        [DllImport("user32.dll")]
        public static extern int GetWindowRect(int hwnd, ref RECT rc);

        public enum VirtualKeys : int
        {
            VK_0 = 0x30,
            VK_1 = 0x31,
            VK_2 = 50,
            VK_3 = 0x33,
            VK_4 = 0x34,
            VK_5 = 0x35,
            VK_6 = 0x36,
            VK_7 = 0x37,
            VK_8 = 0x38,
            VK_9 = 0x39,
            VK_A = 0x41,
            VK_ACCEPT = 30,
            VK_ADD = 0x6b,
            VK_APPS = 0x5d,
            VK_ATTN = 0xf6,
            VK_B = 0x42,
            VK_BACK = 8,
            VK_C = 0x43,
            VK_CANCEL = 3,
            VK_CAPITAL = 20,
            VK_CLEAR = 12,
            VK_CONTROL = 0x11,
            VK_CONVERT = 0x1c,
            VK_CRSEL = 0xf7,
            VK_D = 0x44,
            VK_DECIMAL = 110,
            VK_DELETE = 0x2e,
            VK_DIVIDE = 0x6f,
            VK_DOWN = 40,
            VK_E = 0x45,
            VK_END = 0x23,
            VK_EREOF = 0xf9,
            VK_ESCAPE = 0x1b,
            VK_EXECUTE = 0x2b,
            VK_EXSEL = 0xf8,
            VK_F = 70,
            VK_F1 = 0x70,
            VK_F10 = 0x79,
            VK_F11 = 0x7a,
            VK_F12 = 0x7b,
            VK_F2 = 0x71,
            VK_F3 = 0x72,
            VK_F4 = 0x73,
            VK_F5 = 0x74,
            VK_F6 = 0x75,
            VK_F7 = 0x76,
            VK_F8 = 0x77,
            VK_F9 = 120,
            VK_FINAL = 0x18,
            VK_G = 0x47,
            VK_H = 0x48,
            VK_HANGUL = 0x15,
            VK_HANJA = 0x19,
            VK_HELP = 0x2f,
            VK_HOME = 0x24,
            VK_I = 0x49,
            VK_INSERT = 0x2d,
            VK_J = 0x4a,
            VK_JUNJA = 0x17,
            VK_K = 0x4b,
            VK_L = 0x4c,
            VK_LBUTTON = 1,
            VK_LCONTROL = 0xa2,
            VK_LEFT = 0x25,
            VK_LMENU = 0xa4,
            VK_LSHIFT = 160,
            VK_LWIN = 0x5b,
            VK_M = 0x4d,
            VK_MBUTTON = 4,
            VK_MENU = 0x12,
            VK_MODECHANGE = 0x1f,
            VK_MULTIPLY = 0x6a,
            VK_N = 0x4e,
            VK_NEXT = 0x22,
            VK_NONAME = 0xfc,
            VK_NONCONVERT = 0x1d,
            VK_None = 0,
            VK_NUMLOCK = 0x90,
            VK_NUMPAD0 = 0x60,
            VK_NUMPAD1 = 0x61,
            VK_NUMPAD2 = 0x62,
            VK_NUMPAD3 = 0x63,
            VK_NUMPAD4 = 100,
            VK_NUMPAD5 = 0x65,
            VK_NUMPAD6 = 0x66,
            VK_NUMPAD7 = 0x67,
            VK_NUMPAD8 = 0x68,
            VK_NUMPAD9 = 0x69,
            VK_O = 0x4f,
            VK_OEM_1 = 0xba,
            VK_OEM_2 = 0xbf,
            VK_OEM_3 = 0xc0,
            VK_OEM_4 = 0xdb,
            VK_OEM_5 = 220,
            VK_OEM_6 = 0xdd,
            VK_OEM_7 = 0xde,
            VK_OEM_8 = 0xdf,
            VK_OEM_CLEAR = 0xfe,
            VK_OEM_COMMA = 0xbc,
            VK_OEM_MINUS = 0xbd,
            VK_OEM_PERIOD = 190,
            VK_OEM_PLUS = 0xbb,
            VK_P = 80,
            VK_PA1 = 0xfd,
            VK_PAUSE = 0x13,
            VK_PLAY = 250,
            VK_PRINT = 0x2a,
            VK_PRIOR = 0x21,
            VK_Q = 0x51,
            VK_R = 0x52,
            VK_RBUTTON = 2,
            VK_RCONTROL = 0xa3,
            VK_RETURN = 13,
            VK_RIGHT = 0x27,
            VK_RMENU = 0xa5,
            VK_RSHIFT = 0xa1,
            VK_RWIN = 0x5c,
            VK_S = 0x53,
            VK_SCROLL = 0x91,
            VK_SELECT = 0x29,
            VK_SEPARATOR = 0x6c,
            VK_SHIFT = 0x10,
            VK_SLEEP = 0x5f,
            VK_SNAPSHOT = 0x2c,
            VK_SPACE = 0x20,
            VK_SUBTRACT = 0x6d,
            VK_T = 0x54,
            VK_TAB = 9,
            VK_U = 0x55,
            VK_UP = 0x26,
            VK_V = 0x56,
            VK_W = 0x57,
            VK_X = 0x58,
            VK_XBUTTON1 = 5,
            VK_XBUTTON2 = 6,
            VK_Y = 0x59,
            VK_Z = 90,
            VK_ZOOM = 0xfb
        }
        
        public static int[] MacroKey = new int[]
        {
            0x30,
            0x31,
            0x32,
            0x33,
            0x34,
            0x35,
            0x36,
            0x37,
            0x38,
            0x39,
            0x60,
            0x61,
            0x62,
            0x63,
            0x64,
            0x65,
            0x66,
            0x67,
            0x68,
            0x69,
            0x41,   
            0x42,            
            0x43,           
            0x44,           
            0x45,         
            0x46,
            0x47,
            0x48,
            0x49,
            0x4A,
            0x4B,
            0x4C,
            0x4D,
            0x4E,
            0x4F,
            0x50,
            0x51,
            0x52,
            0x53,
            0x54,
            0x55,
            0x56,
            0x57,
            0x58,
            0x59,
            0x5A,       
            0x70,            
            0x71,
            0x72,
            0x73,
            0x74,
            0x75,
            0x76,
            0x77,
            0x78,
            0x79,
            0x7a,
            0x7b,
            0xA2,
            0xA4,
            0xA0,
            0x2D,
            0x2E,
            0x24,
            0x23,
            0x21,
            0x22,
            0x20,
            0x1B,
            0x0D,
            0x08,
            0x09,
            0x03,
            0x2C,
            0x5B,
            0x26,
            0x28,
            0x25,
            0x27
        };

        public enum MacroKeys : int
        {
            Num_0 = 0x30,
            Num_1 = 0x31,
            Num_2 = 50,
            Num_3 = 0x33,
            Num_4 = 0x34,
            Num_5 = 0x35,
            Num_6 = 0x36,
            Num_7 = 0x37,
            Num_8 = 0x38,
            Num_9 = 0x39,
            NumPad_0 = 0x60,
            NumPad_1 = 0x61,
            NumPad_2 = 0x62,
            NumPad_3 = 0x63,
            NumPad_4 = 100,
            NumPad_5 = 0x65,
            NumPad_6 = 0x66,
            NumPad_7 = 0x67,
            NumPad_8 = 0x68,
            NumPad_9 = 0x69,
            NumPad_Plus = 0x6B,
            NumPad_Minus = 0x6D,
            A = 0x41,   
            B = 0x42,            
            C = 0x43,           
            D = 0x44,           
            E = 0x45,         
            F = 70,
            G = 0x47,
            H = 0x48,
            I = 0x49,
            J = 0x4A,
            K = 0x4B,
            L = 0x4C,
            M = 0x4D,
            N = 0x4E,
            O = 0x4F,
            P = 80,
            Q = 0x51,
            R = 0x52,
            S = 0x53,
            T = 0x54,
            U = 0x55,
            V = 0x56,
            W = 0x57,
            X = 0x58,
            Y = 0x59,
            Z = 90,       
            F1 = 0x70,            
            F2 = 0x71,
            F3 = 0x72,
            F4 = 0x73,
            F5 = 0x74,
            F6 = 0x75,
            F7 = 0x76,
            F8 = 0x77,
            F9 = 120,
            F10 = 0x79,
            F11 = 0x7a,
            F12 = 0x7b,
            Ctrl = 0xA2,
            Alt = 0xA4,
            Shift = 160,
            Insert = 0x2D,
            Delete = 0x2E,
            Home = 0x24,
            End = 0x23,
            PageUp = 0x21,
            PageDown = 0x22,
            Space = 0x20,
            Esc = 0x1B,
            Enter = 13,
            BackSpace = 8,
            Tab = 9,
            Break = 0x13,
            PrintScreen = 0x2C,
            Win = 0x5B,
            Up = 0x26,
            Down = 40,
            Left = 0x25,
            Right = 0x27
        }
        public static string[] MacroKeyName = new string[]
        {
            "Num_0", 
            "Num_1",
            "Num_2",
            "Num_3",
            "Num_4",
            "Num_5",
            "Num_6",
            "Num_7",
            "Num_8",
            "Num_9",
            "NumPad_0",
            "NumPad_1",
            "NumPad_2",
            "NumPad_3",
            "NumPad_4",
            "NumPad_5",
            "NumPad_6",
            "NumPad_7",
            "NumPad_8",
            "NumPad_9",
            "A",
            "B",
            "C",
            "D",
            "E",
            "F",
            "G",
            "H",
            "I",
            "J",
            "K",
            "L",
            "M",
            "N",
            "O",
            "P",
            "Q",
            "R",
            "S",
            "T",
            "U",
            "V",
            "X",
            "W",
            "Y",
            "Z",
            "F1",
            "F2",
            "F3",
            "F4",
            "F5",
            "F6",
            "F7",
            "F8",
            "F9",
            "F10",
            "F11",
            "F12",
            "Ctrl",
            "Alt",
            "Shift",
            "Insert",
            "Delete",
            "Home",
            "End",
            "PageUp",
            "PageDown",
            "Space",
            "Esc",
            "Enter",
            "BackSpace",
            "Tab",
            "Break",
            "PrintScreen",
            "Win",
            "Up",
            "Down",
            "Left",
            "Right"
        };

        // 마우스 이벤트 제어.
        [DllImport( "user32.dll" )]
        public static extern void mouse_event ( uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo );

        [DllImport( "user32.dll" )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool GetCursorPos ( out POINT lpPoint );

        [DllImport( "user32.dll" )]
        public static extern bool SetCursorPos ( int X, int Y );

        [DllImport( "user32.dll" )]
        public static extern int GetWindowLong ( IntPtr hWnd, int nIndex );

        [DllImport( "user32.dll" )]
        public static extern IntPtr SetWindowLong ( IntPtr hWnd, int nIndex, int dwNewLong );

        [DllImport( "user32.dll", SetLastError = true )]
        public static extern IntPtr GetWindow ( IntPtr hWnd, uint uCmd );
        public enum GetWindow_Cmd : uint
        {
            GW_HWNDFIRST = 0,
            GW_HWNDLAST = 1,
            GW_HWNDNEXT = 2,
            GW_HWNDPREV = 3,
            GW_OWNER = 4,
            GW_CHILD = 5,
            GW_ENABLEDPOPUP = 6
        }
        [DllImport( "user32.dll", ExactSpelling = true, CharSet = CharSet.Auto )]
        public static extern IntPtr GetParent ( IntPtr hWnd );

        public enum VirtualMouse : uint
        {
            LEFT_DOWN = 0x00000002,
            LEFT_UP = 0x00000004,
            RIGHT_DOWN = 0x00000008,
            RIGHT_UP = 0x000000010,
            WHEEL = 0x000000800
        }

        [StructLayout( LayoutKind.Sequential )]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [StructLayout( LayoutKind.Sequential )]
        public struct POINT
        {
            public int x;
            public int y;
        }
    }
}
